-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Use a C-safe return type for __rust_[ui]128_*
overflowing intrinsics
#134338
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
r? @wesleywiser rustbot has assigned @wesleywiser. Use |
__rust_[ui]128_*
overflowing intrinsics__rust_[ui]128_*
overflowing intrinsics
Some changes occurred in compiler/rustc_codegen_gcc Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 |
For cranelift, is there a way to load the stack slot so it can be combined with the integer for a |
You can use |
b65b8e5
to
b976550
Compare
This comment has been minimized.
This comment has been minimized.
b976550
to
c2a51c9
Compare
These commits modify the If this was unintentional then you should revert the changes before this PR is merged. |
This comment has been minimized.
This comment has been minimized.
☔ The latest upstream changes (presumably #134844) made this pull request unmergeable. Please resolve the merge conflicts. |
@@ -23,7 +23,8 @@ libloading = { version = "0.8.0", optional = true } | |||
smallvec = "1.8.1" | |||
|
|||
[patch.crates-io] | |||
# Uncomment to use local checkout of cranelift | |||
# todo: remove patch | |||
compiler_builtins = { git = "https://github.com/tgross35/compiler-builtins.git", package = "compiler_builtins", branch = "overflowing-c-safe-ret" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't apply to building the sysroot. Also the patch in library/Cargo.toml should be enough to apply while building a sysroot for cg_clif.
source = "registry+https://github.com/rust-lang/crates.io-index" | ||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" | ||
checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The lockfile changes should be reverted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the entire second commit is just for testing and will be dropped. My plan is once you approve the Cranelift changes and somebody from GCC has looked that portion over, I will merge rust-lang/compiler-builtins#735, drop the second commit (which add my crates-iopatch), replace it with a normal
compiler-builtins` bump, and then this PR's merge will change everything atomically.
However, I am stuck completing the current bump at #135180, so I will hold off until that gets fixed.
c2a51c9
to
7e67edf
Compare
__rust_[ui]128_*
overflowing intrinsics__rust_[ui]128_*
overflowing intrinsics
This comment has been minimized.
This comment has been minimized.
@rust-lang/wg-gcc-backend would one of you mind taking a look at the GCC changes? I am assuming that since this bump means the intrinsics are changing to get the same signature (type aside) as |
7e67edf
to
3c4707e
Compare
This comment has been minimized.
This comment has been minimized.
_ => unreachable!(), | ||
}, | ||
}; | ||
return self.operation_with_overflow(func_name, lhs, rhs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I can see, this change doesn't look right as this will fall to calling self.overflow_call()
below which expects that the overflow flag is returned from the function call (like these GCC intrinsics) whereas your change seems to return the integer result and not the overflow flag.
My guess is that you'll need to keep this special handling and change the method operation_with_overflow
accordingly as these intrinsics are also used in src/intrinsic/mod.rs
.
AFAIK, the only related tests that run in this CI are those lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking a look. Doesn't this block currently sometimes use __mulosi4
without an early turn? After the change to compiler_builtins
, __rust_*128_o
should be consistent with the __mulo*i4
functions.
AFAIK, the only related tests that run in this CI are those lines.
Is there any kind of codegen/asm test that should be added here? Or is the existing test sufficient once CI gets that far.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking a look. Doesn't this block currently sometimes use
__mulosi4
without an early turn? After the change tocompiler_builtins
,__rust_*128_o
should be consistent with the__mulo*i4
functions.
Indeed, it looks like there might be a bug in here.
Is there any kind of codegen/asm test that should be added here? Or is the existing test sufficient once CI gets that far.
What do you mean? There's more tests that are ran in the repo of rustc_codegen_gcc itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, it looks like there might be a bug in here.
I changed this so mulo
and the __rust
functions should now be taking the same codepath, still have to update the rest.
Is there any kind of codegen/asm test that should be added here? Or is the existing test sufficient once CI gets that far.
What do you mean? There's more tests that are ran in the repo of rustc_codegen_gcc itself.
I am just wondering whether I should add another test anywhere to verify the new behavior, especially if __mulosi4
may have been called incorrectly before. And if so, what format/location this should be (for LLVM I'd probably add a codegen test, but I'm not sure what the equivalent would be here).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was expecting that there would be UI tests for these, so that every backend could benefit from them.
Do they have to be codegen tests?
There are integer tests here for the GCC codegen, but they are not ran in the Rust CI, as far as I know, so if it's too much of a pain, we can open an issue to remind me to add tests for this in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at https://rust.godbolt.org/z/eWfPK6rGW it seems like GCC lowers these operations to assembly (LLVM as well), which possibly explains why the test was not failing before even if the __mulosi4
call had a bug. I am not very familiar with this backend but I take it GCC intercepts the call to __builtin_sub_overflow
and adjusts for the correct size?
If it doesn't emit this call then I am not sure what kind of test would work here, but can add something if you have any ideas. I updated the code and it should be ready for review, it builds but have not been able to run tests.
I was expecting that there would be UI tests for these, so that every backend could benefit from them.
Agreed that we should have something end-to-end here, possibly reusing the test generators from compiler-builtins/libm. I think the status quo assumption is that we don't need to test the lowering too heavily since that is the backend's responsibility, but it would still be good to have something systematic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not very familiar with this backend but I take it GCC intercepts the call to
__builtin_sub_overflow
and adjusts for the correct size?
Yes. The doc mentions:
The first built-in function allows arbitrary integral types for operands and the result type must be pointer to some integral type other than enumerated or boolean type, the rest of the built-in functions have explicit integer types.
I reviewed your code: it looks good, thanks!
This test does call overflowing_mul
, so I'm not sure why it wasn't tested there.
Any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test does call
overflowing_mul
, so I'm not sure why it wasn't tested there. Any ideas?
In order to hit the branch where __mulosi
/__mulodi
gets emitted, the self.is_native_int_type(lhs.get_type())
condition has to fail for i32
or i64
- I'm guessing there probably aren't many platforms where that would happen. The calls to __rust_i128_*
were correct before but it looks like is_native_int_type
has to be returning true for i128
too, at least on x86, since that gets asm lowering https://rust.godbolt.org/z/jPfMK5vhv. I take it maybe the gcc-13-without-int128
CI jobs in the cg_gcc repo would cover this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that CI job uses a GCC where 128-bit integers are disabled to test this indeed.
Right, that must be why it wasn't tested. But I think i64
is supported on all platforms, so I'll open an issue to check that.
This comment has been minimized.
This comment has been minimized.
let res_ty = match width { | ||
32 => self.tcx.types.i32, | ||
64 => self.tcx.types.i64, | ||
128 => self.tcx.types.i128, | ||
_ => unreachable!("unexpected integer size"), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was there a reason to do that instead of reusing a_type
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe a_type
is the GCC type and I need the rustc type to calculate the layout. I could not find a way to convert in this direction - is there one? Or a way to get a layout directly from the GCC type (feel like I might be missing something here).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry I forgot that you now have multiple types to handle here and not only 128-bit integers.
It's good as it is.
let oflow_param_type = oflow_type.make_pointer(); | ||
let res_type = a_type; | ||
|
||
let oflow_value = self.current_func().new_local(self.location, oflow_type, "overflow"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rename all oflow
to overflow
to make it a bit clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is done
fa73f0d
to
c76888f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me.
Thanks a lot!
# todo: remove patch | ||
compiler_builtins = { git = "https://github.com/tgross35/compiler-builtins.git", package = "compiler_builtins", branch = "NOMERGE-overflowing-c-safe-ret-version" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only this to remove, I guess.
Thanks for reviewing! Actually merging this is still blocked until I can update compiler-builtins. Once that works again, I'll drop the Cargo patches, bump the version, and merge this. @rustbot blocked |
☔ The latest upstream changes (presumably #135180) made this pull request unmergeable. Please resolve the merge conflicts. |
Combined with [1], this will change the overflowing multiplication operations to return an `extern "C"`-safe type. Link: rust-lang/compiler-builtins#735 [1]
0.1.142 fixes an issue parsing optimization flags, and 0.1.143 changes `__rust_[ui]128_*` builtins to use a C-safe signature.
c76888f
to
f6a2db8
Compare
My diagnostics fix merged, which meant the r-l/rust update to builtins 0.1.141 could merge, which meant I could merge the signature changes to builtins, and now this is finally unblocked. Dropped the branch override patch and replaced it with a bump to builtins 0.1.143. Cranelift tests pass locally. @bors r=bjorn3,antoyo |
Combined with [1], this will change the overflowing multiplication operations to return an
extern "C"
-safe type.Link: rust-lang/compiler-builtins#735 [1]